﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Zocono.Infrastructure.Common;
using Zocono.WCS.Domain.DomainRepository;
using Zocono.WCS.Domain.EntityInfo;
using Zocono.WCS.Infrastructure.ApllicationDto;
using Zocono.WCS.Infrastructure.ApllicationDto.DtoWcsManage;

namespace Zocono.WCS.Domain.LogDomain
{
    public class RunLogInfoService : IRunLogInfoService
    {
        private readonly IRunLogRepository _IRunLogRepository;
        private readonly ISnowflake _Snowflake;
        private readonly ILogUtil _logUtil;
        private readonly IServiceScopeFactory _IServiceScopeFactory;



        public RunLogInfoService(IRunLogRepository iRunLogRepository, 
            ISnowflake snowflake, 
            IServiceScopeFactory serviceScopeFactory,
            ILogUtil logUtil
            )
        {
            _IRunLogRepository = iRunLogRepository;
            _Snowflake = snowflake;
            _IServiceScopeFactory = serviceScopeFactory;
            _logUtil = logUtil;
        }



        //public async Task<bool> AddRunLogInfoAsync(RunLogInfo runLogInfo)
        //{
        //    bool isIdExist = true;
        //    long rLogId = 0;
        //    while (isIdExist)
        //    {
        //        rLogId = _Snowflake.GetId();
        //        RunLogInfo existingRunLog = await _IRunLogRepository.GetByIdAsync(rLogId);
        //        isIdExist = existingRunLog != null;
        //    }

        //    runLogInfo.RLogId = rLogId;
        //    runLogInfo.CreateTime = DateTime.Now;
        //    return await _IRunLogRepository.InsertAsync(runLogInfo);
        //}

        //public async Task<bool> AddRunLogInfoAsync(RunLogInfo runLogInfo)
        //{
        //    // Key: ID, Value: 是否已使用
        //    Dictionary<long, bool> idCache = new Dictionary<long, bool>();
        //    bool isIdExist = true;
        //    long rLogId = 0;
        //    while (isIdExist)
        //    {
        //        // 先从缓存中获取ID
        //        if (idCache.Count > 0)
        //        {
        //            rLogId = idCache.FirstOrDefault(x => x.Value == false).Key;
        //            idCache[rLogId] = true;
        //        }
        //        else
        //        {
        //            // 生成新的ID
        //            rLogId = _Snowflake.GetId();
        //            idCache.Add(rLogId, true);
        //        }
        //        RunLogInfo existingRunLog = await _IRunLogRepository.GetByIdAsync(rLogId);
        //        isIdExist = existingRunLog != null;
        //        if (isIdExist)
        //        {
        //            // 标记ID已使用过
        //            idCache[rLogId] = true;
        //        }
        //    }

        //    runLogInfo.RLogId = rLogId;
        //    runLogInfo.CreateTime = DateTime.Now;
        //    return await _IRunLogRepository.InsertAsync(runLogInfo);
        //}



        //private async void FlushCacheAsync(object state)
        //{
        //    try
        //    {
        //        List<RunLogInfo> insertList = new List<RunLogInfo>();

        //        // 使用lock语句保证线程安全
        //        lock (_lockObj)
        //        {
        //            if (_cacheList.Count == 0)
        //            {
        //                return;
        //            }

        //            foreach (var item in _cacheList)
        //            {
        //                if (!insertList.Any(x => x.RLogId == item.RLogId))
        //                {
        //                    insertList.Add(item);
        //                }
        //                else
        //                {
        //                    // 如果生成的ID已经存在于插入列表中，则重新生成并记录日志
        //                    _logger.LogWarning($"Duplicate ID found: {item.RLogId}");
        //                    while (insertList.Any(x => x.RLogId == item.RLogId))
        //                    {
        //                        item.RLogId = _Snowflake.GetId();
        //                    }
        //                    insertList.Add(item);
        //                }
        //            }


        //            foreach (var item in _cacheList)
        //            {
        //                string key = $"{item.RunLog}-{item.RunType}-{item.EquipmentCode}-{item.ContainerBarcode}";
        //                if (!insertList.Any(x => $"{x.RunLog}-{x.RunType}-{x.EquipmentCode}-{x.ContainerBarcode}" == key))
        //                {
        //                    insertList.Add(item);
        //                }
        //                else
        //                {
        //                    // 如果相同的日志信息已经存在于插入列表中，则重新生成RLogId并记录日志
        //                    _logger.LogWarning($"Duplicate log found: {key}");
        //                    long newRLogId = _Snowflake.GetId();
        //                    while (insertList.Any(x => x.RLogId == newRLogId))
        //                    {
        //                        newRLogId = _Snowflake.GetId();
        //                    }
        //                    item.RLogId = newRLogId;
        //                    insertList.Add(item);
        //                }
        //            }

        //            _cacheList.Clear();
        //        }

        //        // 调用异步方法将数据写入数据库中
        //        await _IRunLogRepository.InsertRangeAsync(insertList);
        //    }
        //    catch (Exception ex)
        //    {
        //        // 记录日志并执行相应的处理代码
        //        _logger.LogError(ex, "日志写入数据库失败.");
        //        // TODO: 执行相应的处理代码
        //    }
        //}

        //注释清理掉就是原来代码
        public async Task<bool> AddRunLogInfoAsync(RunLogInfo runLogInfo)
        {
            try
            {
                runLogInfo.RLogId = _Snowflake.GetId_RLogId();
                runLogInfo.CreateTime = DateTime.Now;
                using var scope = _IServiceScopeFactory.CreateScope();
                await scope.ServiceProvider.GetRequiredService<IRunLogRepository>().InsertAsync(runLogInfo);
                //_logUtil.Error
                //return await _IRunLogRepository.InsertAsync(runLogInfo);
                return true;
            }
            catch (Exception ex)
            {
                _logUtil.Error($"添加流程日志日志失败={ex}");
                return false;
            }
            finally
            {
                _logUtil.Trace($"托盘码【{runLogInfo?.ContainerBarcode}】在设备号【{runLogInfo?.EquipmentCode}】交互日志内容为：{runLogInfo?.RunLog}");
            }
            //try
            //{
            //    var loginfo = await _IRunLogRepository.AsSugarClient().Queryable<RunLogInfo>().With(SqlWith.NoLock)
            //        .Where(it => it.EquipmentCode == runLogInfo.EquipmentCode
            //            && it.ContainerBarcode == runLogInfo.ContainerBarcode
            //            && it.RunLog == runLogInfo.RunLog
            //            && it.RunType == runLogInfo.RunType)
            //        .OrderBy(it => it.CreateTime, OrderByType.Desc)
            //        .FirstAsync();

            //    if (loginfo != null)
            //    {
            //        loginfo.CreateTime = DateTime.Now;
            //        return await _IRunLogRepository.UpdateAsync(loginfo);
            //    }
            //    else
            //    {
            //        runLogInfo.RLogId = _Snowflake.GetId();
            //        runLogInfo.CreateTime = DateTime.Now;
            //        return await _IRunLogRepository.InsertAsync(runLogInfo);
            //    }
            //}
            //catch (Exception ex)
            //{
            //    _logUtil.Error($"操作运行日志报错ex={ex.Message}");
            //    return false;
            //}

        }






        //public async Task<bool> AddRunLogInfoAsync(RunLogInfo runLogInfo)
        //{
        //    try
        //    {
        //        //string RunLog = runLogInfo.RunLog; // 假设日志内容保存在 RunLog 属性中
        //        //string EquipmentCode = runLogInfo.EquipmentCode;
        //        //var existingLog = await _IRunLogRepository.FindByContentAsync(RunLog, EquipmentCode);
        //        RunLogInfo logininfo = null;
        //        try
        //        {

        //            logininfo = await _IRunLogRepository.AsSugarClient().Queryable<RunLogInfo>()
        //            .Where(it => it.EquipmentCode == runLogInfo.EquipmentCode
        //            && it.ContainerBarcode == runLogInfo.ContainerBarcode
        //            && it.RunLog.Contains(runLogInfo.RunLog)
        //            && it.RunType == runLogInfo.RunType).FirstAsync();
        //        }
        //        catch (Exception ex)
        //        {
        //            _logUtil.Error($"查询重复日志数据报错，错误代码：{ex.Message}");
        //            logininfo = null;
        //        }
        //        if (logininfo != null)
        //        {
        //            logininfo.CreateTime = DateTime.Now;
        //            return await _IRunLogRepository.UpdateAsync(logininfo);
        //            //return true;
        //        }
        //        else
        //        {
        //            runLogInfo.RLogId =_Snowflake.GetId_RLogId();
        //            runLogInfo.CreateTime = DateTime.Now;
        //            return await _IRunLogRepository.InsertAsync(runLogInfo);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        _logUtil.Error($"添加流程日志日志失败{JsonHelper.SerializeObject(runLogInfo)},{ex}");
        //        return false;
        //    }
        //}








        public async Task<PageDto<RunLogInfoDto>> GetRunLogInfoAsync(RunLogInfoDto runLogInfo)
        {
            PageModel page = new PageModel { PageIndex = runLogInfo.PageIndex, PageSize = runLogInfo.PageSize, };
            PageDto<RunLogInfoDto> pageDto = new PageDto<RunLogInfoDto>();
            RefAsync<int> totalNumber = 0;
            var exp = Expressionable.Create<RunLogInfo>();
            exp.AndIF(!string.IsNullOrEmpty(runLogInfo.StarTime), l => l.CreateTime >= runLogInfo.StarTime.ToDateTimeFormat("yyyy-MM-dd HH:mm"));
            exp.AndIF(!string.IsNullOrEmpty(runLogInfo.EndTime), l => l.CreateTime < runLogInfo.EndTime.ToDateTimeFormat("yyyy-MM-dd HH:mm"));
            exp.AndIF(!string.IsNullOrEmpty(runLogInfo.ContainerBarcode), l => l.ContainerBarcode.Contains(runLogInfo.ContainerBarcode)  );
            exp.AndIF(!string.IsNullOrEmpty(runLogInfo.EquipmentCode), l => l.EquipmentCode.Contains(runLogInfo.EquipmentCode));
            exp.AndIF(!string.IsNullOrEmpty(runLogInfo.RunType), l => l.RunType.Contains(runLogInfo.RunType));
            exp.AndIF(!string.IsNullOrEmpty(runLogInfo.RunLog), l => l.RunLog.Contains(runLogInfo.RunLog));
            var result = await _IRunLogRepository.AsSugarClient().Queryable<RunLogInfo>()
                .Where(exp.ToExpression())
                .OrderBy(l => l.CreateTime, OrderByType.Desc)
                .Select(l => new RunLogInfoDto
                {
                    RLogId = l.RLogId,
                    RunLog = l.RunLog,
                    RunType = l.RunType,
                    ContainerBarcode = l.ContainerBarcode,
                    CreateTime = l.CreateTime,
                    EquipmentCode = l.EquipmentCode
                }).ToPageListAsync(page.PageIndex, page.PageSize, totalNumber);
            pageDto.Result = result;
            pageDto.Total = totalNumber;
            return pageDto;
        }

        public async Task<string> GetScCodeByCKTCodeAsync(string CKTCode)
        {
            var result = await _IRunLogRepository.AsSugarClient().Queryable<SCInfo>()
                .Where(c => c.Warehouse1 == CKTCode || c.Warehouse2 == CKTCode).FirstAsync();
            if (result != null)
            {
                return result.StackerCode;
            }
            return "";
        }
        

        public async Task RemoveDuplicateRunLog()
        {
            // 查询所有的记录
            var allRecords = _IRunLogRepository.AsQueryable().ToList();

            // 按照 EquipmentCode、ContainerBarcode、RunLog、RunType 进行分组，
            // 相同的分到一组，不同的分到不同组
            var groups = allRecords.GroupBy(
                r => new {
                  EquipmentCode = r.EquipmentCode,
                  ContainerBarcode = r.ContainerBarcode,
                  RunLog = r.RunLog,
                  RunType = r.RunType
              }
            );


            //// 遍历每个分组，如果有多于一个记录，则删除除第一个以外的所有记录
            //foreach (var group in groups)
            //{
            //    if (group.Count() > 1)
            //    {
            //        var recordsToDelete = group.Skip(1);
            //        foreach (var record in recordsToDelete)
            //        {
            //            _IRunLogRepository.Delete(record);
            //        }
            //    }
            //}

            foreach (var group in groups)
            {
                // 保留该组中的第一个元素，删除其他元素
                var firstRecord = group.First();
                var otherRecords = group.Skip(1);
                foreach (var record in otherRecords)
                {
                    List<RunLogInfo> logininfos = null;
                    try
                    {
                        logininfos = await _IRunLogRepository.AsSugarClient().Queryable<RunLogInfo>()
                            .Where(it => it.EquipmentCode == record.EquipmentCode
                            && it.ContainerBarcode == record.ContainerBarcode
                            && it.RunLog.Contains(record.RunLog)
                            && it.RunType == record.RunType).ToListAsync();
                        var tempList = logininfos.Skip(1);
                        foreach (var item in tempList)
                        {
                            await _IRunLogRepository.DeleteAsync(item);
                        }
                    }
                    catch (Exception ex)
                    {
                        _logUtil.Error($"查询重复日志数据报错，错误代码：{ex.Message}");
                    }
                }
            }

        }

    }
}

    
   
